package com.edu.html.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.edu.common.constant.CONSTANT;
import com.edu.html.pojo.User;
import com.edu.html.service.UserService;

public class ShiroDbRealm extends AuthorizingRealm{
	
	 @Autowired  
     private UserService userService;  
	 
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		User user = (User) SecurityUtils.getSubject().getSession().getAttribute(CONSTANT.SESSION_USER_KEY);  
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
        info.addRole(user.getRole().trim());  
        return info;  
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		// 把token转换成User对象  
        String username = (String) authcToken.getPrincipal();//tokenToUser((UsernamePasswordToken) authcToken);  
        // 验证用户是否可以登录  
        User user = userService.login(username);  
        if(user == null)  
        	new UnknownAccountException();//没找到帐号   
        // 判断帐号是否锁定  
        if (Boolean.TRUE.equals(user.getLocked())) {  
            // 抛出 帐号锁定异常  
            throw new LockedAccountException();  
        } 
        // 设置session  
        Session session = SecurityUtils.getSubject().getSession();  
        session.setAttribute(CONSTANT.SESSION_USER_KEY, user); 
        //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配，如果觉得人家的不好可以自定义实现  
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(  
                user.getUsername(), //用户名  
                user.getPassword(), //密码  
                ByteSource.Util.bytes(user.getCredentialsSalt()),//salt=username+salt  
                getName()  //realm name  
        );  
        return authenticationInfo; 
	}
	
	public final UserService getUserService() {
		return userService;
	}

	public final void setUserService(UserService userService) {
		this.userService = userService;
	}  
	
}
